from flask import Blueprint, request,session
import os
import json
import paramiko
from utils import handle_exception, handle_success, get_global_config
from utilsNetwork import ssh_connect, check_jdk_installed, install_jmeter, modify_local_jmeter_properties, \
    start_jmeter_server_linux, execute_command_linux,get_json_content, transfer_jmeter_properties
from db_handler import db_handler
import ast


machineManagement = Blueprint('machineManagement', __name__)


# 测试机ssh校验
# 新增测试机-弹出对话框-点击“测试连接”按钮
# 参数：ip、password、username
@machineManagement.route('/file/testingConnection', methods=['POST'])
def testing_connection():
    try:
        params = request.json
        ip = params["ip"]
        password = params["password"]
        username = params["username"]
        success, message = ssh_connect(ip, username, password)

        if success:
            return handle_success(True, "连接成功")
        else:
            return handle_exception(message, "连接失败")

    except Exception as err:  # 捕获异常
        return handle_exception(err, "程序异常")

# 假设 JSON 文件的路径是 'config.json'
json_file_path = 'config.json'


# 在操作slaver之前，检查该机器是否被占用
def is_machine_locked(ip):
    query = "SELECT lock_user FROM slaver WHERE ip = %s"
    result = db_handler.execute_query(query, (ip,))
    return result[0]['lock_user'] is not None and result[0]['lock_user'] != ""

# 初始化测试环境
# 操作-初始化(进行完初始化才可以点启动按钮，且按钮变成“已初始化”)
# 参数：ip、password、username
@machineManagement.route('/file/checkEnvironment', methods=['POST'])
def check_environment():
    try:
        params = request.json
        ip = params["ip"]
        password = params["password"]
        username = params["username"]
        check_status = False

        local_jmeter_path = get_global_config()['jmeterPath']
        properties_file = os.path.join(local_jmeter_path, 'bin/jmeter.properties')
        remote_hosts = ip
        jvmXms = '8g'
        jvmXmx = '24g'

        if is_machine_locked(ip):  # 检查机器是否被占用
            return handle_exception("该机器已被占用", "操作失败")

        check_jdk_installed(ip, username, password)  # 检查是否安装JDK，若没有安装则为其安装
        install_jmeter(ip, username, password, jvmXms, jvmXmx)  # 远程机器上安装Jmeter并修改server.rmi.ssl.disable的值，以及设置JVM
        modify_local_jmeter_properties(properties_file,
                                       remote_hosts)  # 向本地jmeter的remote_host追加ip、修改server.rmi.ssl.disable的值
        check_status = True
    except Exception as err:  # 捕获异常
        return handle_exception(err, "程序异常")
    else:
        if check_status:
            return handle_success("success", "初始化成功")
        else:
            return handle_exception(Exception("error"), "初始化失败")


# 启动jmeter-server
# 操作-启动
# 参数：ip、password、username
@machineManagement.route('/file/startJmeter', methods=['POST'])
def start_jmeter_server():
    try:
        params = request.json
        ip = params["ip"]
        password = params["password"]
        username = params["username"]

        if is_machine_locked(ip):  # 检查机器是否被占用
            return handle_exception("该机器已被占用", "操作失败,该机器已被占用")

        start_jmeter_server_linux(ip, username, password)  # 启动jmeter-server
        update_sql = 'UPDATE slaver SET lock_user= %s,is_select= %s  WHERE ip=%s'
        db_handler.execute_update(update_sql, ('', 0, ip))

    except Exception as err:  # 捕获异常
        return handle_exception(err, "程序异常")
    else:
        return handle_success("success", "jmeter启动成功")


# 检查是否启动jmeter-server
# 操作-检查启动
# 参数：ip、password、username
@machineManagement.route('/file/checkJmeterIsOpen', methods=['POST'])
def check_jmeter_server_is_open():
    try:
        params = request.json
        ip = params["ip"]
        password = params["password"]
        username = params["username"]

        ssh_client = paramiko.SSHClient()
        ssh_client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
        ssh_client.connect(ip, username=username, password=password)
        output = execute_command_linux(ssh_client, 'ps -ef | grep jmeter-server | grep -v grep')
        # 关闭SSH连接
        ssh_client.close()
        if './jmeter-server' in output:
            return handle_success("jmeter-server 已启动", "jmeter-server 已启动")
        else:
            return handle_exception("jmeter-server 未启动", "jmeter-server 未启动")
    except Exception as err:  # 捕获异常
        return handle_exception(err, "程序异常")


# 新增测试机
# 新增测试机-弹出对话框-点击“确定”按钮，在未进行连接测试时该按钮置灰
# 参数：ip、password、username
# 返回值： {"centos_type": "Linux","ip": "10.58.100","password": "123.abc","status": true,"username": "root"}
@machineManagement.route('/file/addTestingMachine', methods=['POST'])
def add_testing_machine():
    try:
        params = request.json
        ip = params["ip"]
        username = params["username"]
        password = params["password"]
        centos_type = "Linux"
        jvmXms = params["xms"]
        jvmXmx = params["xmx"]
        status = 0
        is_select = 0

        #改为数据库操作
        db_handler.update_or_insert_server(ip,username,password,centos_type,jvmXms,jvmXmx,status,is_select,"")

        install_jmeter(ip, username, password, jvmXms, jvmXmx)  # 远程机器上安装Jmeter并修改server.rmi.ssl.disable的值，以及设置JVM

    except Exception as err:  # 捕获异常
        return handle_exception(err, "程序异常")
    else:
        return handle_success('负载机', "添加成功")


# 编辑测试机
@machineManagement.route('/file/editTestingMachine', methods=['POST'])
def edit_testing_machine():
    try:
        params = request.json
        ip = params["ip"]
        username = params["username"]
        password = params["password"]
        centos_type = "Linux"
        jvmXms = params["xms"]
        jvmXmx = params["xmx"]
        status = 0
        is_select = 0

        #改为数据库操作
        db_handler.update_or_insert_server(ip,username,password,centos_type,jvmXms,jvmXmx,status,is_select,"")

        transfer_jmeter_properties(ip, username, password, jvmXms, jvmXmx)  # 修改jvm并把文件传到远处机器上

    except Exception as err:  # 捕获异常
        return handle_exception(err, "程序异常")
    else:
        return handle_success('添加成功', "添加成功")

# 获取测试机信息
# 进入“测试机管理”页面时
# 参数：ip、pageNum、pageSize
# 返回值： data": {
#         "list": [
#             {
#                 "centos_type": "Linux",
#                 "ip": "10.58.20.24",
#                 "is_select": true,
#                 "password": "xncs.2023",
#                 "status": true,
#                 "username": "root"
#             }
#         ],
#         "total": 1
#     },
@machineManagement.route('/file/getMachineInfo', methods=['POST'])
def get_machine_info():
    try:
        if 'userid' not in session or 'loginname' not in session:
            return handle_exception("会话失效", "会话失效，请重新登录")

        # PROJECT_ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))  # 根目录
        # json_file_path = os.path.join(PROJECT_ROOT, 'Solo/static/machineInfo.json')
        #
        # # 检查文件是否存在
        # if not os.path.exists(json_file_path):
        #     with open(json_file_path, 'w') as file:
        #         file.write("[]")
        #
        # # 读取 JSON 文件内容
        # with open(json_file_path, 'r') as file:
        #     data = json.load(file)

        # 获取请求参数
        params = request.json
        search_ip = params.get("ip", "")
        pageNum = int(params.get("pageNum", 1))  # 默认第一页
        pageSize = int(params.get("pageSize", 20))  # 默认每页20条

        # 根据 IP 进行模糊搜索过滤
        # if search_ip:
        #
        #     filtered_data = [item for item in data if search_ip in item["ip"]]
        # else:
        #     filtered_data = data

        # 计算分页的起始和结束索引
        # start_index = (pageNum - 1) * pageSize
        # end_index = start_index + pageSize
        #
        # # 分页后的数据
        # paginated_data = filtered_data[start_index:end_index]


        # 构造返回结果
        # result = {
        #     "list": paginated_data,
        #     "total": len(filtered_data)  # 总条目数
        # }

        # 构建查询语句
        query = "SELECT * FROM slaver WHERE ip LIKE %s LIMIT %s, %s"
        start_index = (pageNum - 1) * pageSize
        search_ip_like = f"%{search_ip}%"

        # 执行查询
        result_data = db_handler.execute_query(query, (search_ip_like, start_index, pageSize))

        # 转换'status'和'is_select'为布尔类型
        for item in result_data:
            for key in ['status', 'is_select']:
                if key in item:
                    item[key] = bool(item[key])

        # 获取总条目数
        count_query = "SELECT COUNT(*) as total FROM slaver WHERE ip LIKE %s"
        total_count = db_handler.execute_query(count_query, (search_ip_like,))[0]['total']

        # 构造返回结果
        result = {
            "list": result_data,
            "total": total_count
        }

        return handle_success(result, "查询成功")
    except Exception as err:
        return handle_exception(err, "程序异常")


# 删除测试机
# 操作-删除
# 参数：ip
# 返回值： {"centos_type": "Linux","ip": "10.58.100","password": "123.abc","status": true,"username": "root"}
@machineManagement.route('/file/deleteTestingMachine', methods=['POST'])
def delete_testing_machine():
    try:

        user_id = session['userid']
        params = request.json
        ip_to_delete = params["ip"]
        # PROJECT_ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))  # 根目录
        # json_file_path = os.path.join(PROJECT_ROOT, 'Solo\static\machineInfo.json')
        #
        # # 检查文件是否存在，不存在则返回错误
        # if not os.path.exists(json_file_path):
        #     return handle_exception("JSON文件不存在", "JSON文件不存在")
        #
        # with open(json_file_path, 'r') as file:
        #     data = json.load(file)
        #
        # # 查找并删除指定IP的记录
        # new_data = [item for item in data if item["ip"] != ip_to_delete]
        #
        # # 检查是否有数据被删除
        # if len(new_data) == len(data):
        #     return handle_exception("未找到指定IP的记录", "未找到指定IP的记录")
        #
        # # 将更新后的数据写回文件中
        # with open(json_file_path, 'w') as file:
        #     json.dump(new_data, file, indent=4)

        # 查询用户信息以获取是否为管理员
        query = "SELECT is_admin FROM User WHERE id = %s"
        user_info = db_handler.execute_query(query, (user_id,))

        if not user_info:
            return handle_exception("用户信息获取失败", "用户信息获取失败")

        is_admin = user_info[0]['is_admin']

        if not is_admin:
            return handle_exception("权限不足", "只有管理员才能删除负载机")

        if is_machine_locked(ip_to_delete):  # 检查机器是否被占用
            return handle_exception("该机器已被占用", "操作失败,该机器已被占用")

        del_sql = 'DELETE FROM slaver WHERE ip = %s'
        db_handler.delete(del_sql, (ip_to_delete,))


    except Exception as err:  # 捕获异常
        return handle_exception(err, "程序异常")
    else:
        return handle_success( ip_to_delete,"删除成功")


# 测试机禁用/启用
@machineManagement.route('/file/machineIsEnable', methods=['POST'])
def machine_is_enable():
    try:
        params = request.json
        ip = params["ip"]
        if is_machine_locked(ip):  # 检查机器是否被占用
            return handle_exception("该机器已被占用", "操作失败,该机器已被占用")

        # PROJECT_ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))  # 根目录
        # json_file_path = os.path.join(PROJECT_ROOT, 'Solo\static\machineInfo.json')
        #
        # # 检查文件是否存在，不存在则返回异常
        # if not os.path.exists(json_file_path):
        #     return handle_exception("机器信息文件不存在", "机器信息文件不存在")
        #
        # # 读取 JSON 文件
        # with open(json_file_path, 'r') as file:
        #     data = json.load(file)
        #
        # # 查找并更新对应IP的记录
        # found = False
        # for item in data:
        #     if item["ip"] == ip:
        #         item["status"] = not item["status"]
        #         found = True
        #         break
        #
        # # 如果找不到对应IP的记录，则返回异常
        # if not found:
        #     return handle_exception("未找到对应IP的机器", "未找到对应IP的机器")
        #
        # # 将更新后的数据写回文件
        # with open(json_file_path, 'w') as file:
        #     json.dump(data, file, indent=4)
        query_sql="SELECT status FROM slaver WHERE ip= %s "
        update_sql = 'UPDATE slaver SET status = %s ,is_select= %s WHERE ip= %s'
        now_status=db_handler.execute_query(query_sql,(ip,))[0]
        if now_status["status"]==1:
            db_handler.update(update_sql, (0,0,ip))
        else:
            db_handler.update(update_sql, (1,0,ip))

    except Exception as err:  # 捕获异常
        return handle_exception(err, "程序异常")
    else:
        return handle_success("成功", "状态更新成功")
